﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace GraphDrawer {
	public partial class InoculationPanel : UserControl {
		InoculationStrategies controller;
		GraphProvider.GraphProviderServiceSoapClient cl;
		GraphProvider.Graph output;
		object graph;
		Type graphType;
		int vaccinesCount;

		List<KeyValuePair<GraphProvider.GraphElement, double>> map;

		public InoculationPanel(InoculationStrategies controller, GraphProvider.GraphProviderServiceSoapClient cl) {
			InitializeComponent();

			this.controller = controller;
			this.cl = cl;

			this.SizeChanged += new SizeChangedEventHandler(InoculationPanel_SizeChanged);
			this.cl.GetAvailableMethodsOfCentralityCompleted += new EventHandler<GraphProvider.GetAvailableMethodsOfCentralityCompletedEventArgs>(cl_GetAvailableMethodsOfCentralityCompleted);
			this.cl.ComputeCentralityCompleted += new EventHandler<GraphProvider.ComputeCentralityCompletedEventArgs>(cl_ComputeCentralityCompleted);
			this.cl.ComputeCentralityFromGraphMLCompleted += new EventHandler<GraphProvider.ComputeCentralityFromGraphMLCompletedEventArgs>(cl_ComputeCentralityFromGraphMLCompleted);
		}

		void cl_ComputeCentralityFromGraphMLCompleted(object sender, GraphProvider.ComputeCentralityFromGraphMLCompletedEventArgs e) {
			output = e.Result;
			ComputeCentralityCompleted();
		}

		void cl_ComputeCentralityCompleted(object sender, GraphProvider.ComputeCentralityCompletedEventArgs e) {
			output = e.Result;
			ComputeCentralityCompleted();
		}

		void ComputeCentralityCompleted() {
			PatientsList.Items.Clear();

			map = new List<KeyValuePair<GraphDrawer.GraphProvider.GraphElement, double>>();
			foreach (var item in ((GraphProvider.Graph)output).Vertices)
				foreach (var key in item.Keys)
					if (key.Key == "importance")
						map.Add(new KeyValuePair<GraphProvider.GraphElement, double>
							(item, Convert.ToDouble(key.Value)));
			map.Sort((firstPair, nextPair) => {
				return -firstPair.Value.CompareTo(nextPair.Value);
			});

			int i = 1;
			foreach (var item in map) {
				string name = i.ToString() + ". ";
				string surname = string.Empty;
				foreach (var key in item.Key.Keys)
					if (key.Key == "name")
						name += key.Value;
					else if (key.Key == "surname")
						surname += key.Value;
				PatientsList.Items.Add(name + " " + surname);
				i++;
				if (i > vaccinesCount)
					break;
			}
			GeneratePatientsList.IsEnabled = true;
		}

		private void PatientsList_SelectionChanged(object sender, SelectionChangedEventArgs e) {
			this.PatientDetails.Text = string.Empty;

			if (PatientsList.SelectedItem != null) {
				string patient = PatientsList.SelectedItem.ToString();
				int i = 1;
				foreach (var item in map) {
					string name = i.ToString() + ". ";
					string surname = string.Empty;
					foreach (var key in item.Key.Keys)
						if (key.Key == "name")
							name += key.Value;
						else if (key.Key == "surname")
							surname += key.Value;
					if (patient == name + " " + surname) {
						foreach (var key in item.Key.Keys)
							this.PatientDetails.Text += key.Key + " = " + key.Value + "\n";
						break;
					}
					i++;
				}
			}
		}

		void cl_GetAvailableMethodsOfCentralityCompleted(object sender, GraphProvider.GetAvailableMethodsOfCentralityCompletedEventArgs e) {
			CentralitiesMeasures.Items.Clear();
			foreach (string item in e.Result)
				CentralitiesMeasures.Items.Add(item);
			if (CentralitiesMeasures.Items.Count > 0) {
				CentralitiesMeasures.SelectedIndex = 0;
				CentralityMeasureDescription.Text = GetCentralityMeasureDescription(CentralitiesMeasures.SelectedItem.ToString());
			}
		}

		string GetCentralityMeasureDescription(string name) {
			Type res = typeof(Resource);
			string description = (string)res.GetProperty(name, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static).GetValue(null, null);
			return description;
		}

		public void Init(object graph, Type graphType) {
			this.graph = graph;
			this.graphType = graphType;
			this.map = null;
			this.PatientDetails.Text = string.Empty;
			PatientsList.Items.Clear();
			cl.GetAvailableMethodsOfCentralityAsync();
		}

		void InoculationPanel_SizeChanged(object sender, SizeChangedEventArgs e) {
			CentralitiesMeasures.Height = e.NewSize.Height - 195;
			PatientsList.Height = e.NewSize.Height - 180;
		}

		private void GeneratePatientsList_Click(object sender, RoutedEventArgs e) {
			int count;
			if (Int32.TryParse(VaccinesCount.Text, out count) == false)
				VaccinesCount.Text = "Insert integer";
			else if (count <= 0)
				VaccinesCount.Text = "Positive only";
			else if (CentralitiesMeasures.SelectedItem != null) {
				GeneratePatientsList.IsEnabled = false;
				vaccinesCount = count;
				if (graphType == typeof(string))
					cl.ComputeCentralityFromGraphMLAsync(CentralitiesMeasures.SelectedItem.ToString(),
						(string)graph);
				else if (graphType == typeof(GraphProvider.Graph))
					cl.ComputeCentralityAsync(CentralitiesMeasures.SelectedItem.ToString(),
						(GraphProvider.Graph)graph);
			}
		}

		private void CentralitiesMeasures_SelectionChanged(object sender, SelectionChangedEventArgs e) {
			if (CentralitiesMeasures.SelectedItem != null)
				CentralityMeasureDescription.Text = GetCentralityMeasureDescription(CentralitiesMeasures.SelectedItem.ToString());
		}
	}
}
